<template>
  <ion-page>
    <ion-header>
      <ion-toolbar>
        <ion-buttons slot="start">
          <ion-button @click="onCancel">取消</ion-button>
        </ion-buttons>
        <ion-title>地图</ion-title>
        <ion-buttons slot="end">
          <ion-button @click="onOK">确认</ion-button>
        </ion-buttons>
      </ion-toolbar>
    </ion-header>
    <ion-content>
      <ion-header>
          <ion-searchbar :value="address" @ionChange="search($event)" @ionClear="clearSearchList()"></ion-searchbar>
          <div id="map__result" class="content-result"></div>
      </ion-header>
      <ion-content>
          <el-amap
              vid="amap"
              ref="map"
              class="app-map"
              :zoom="12"
              :plugin="plugin"
              :events="events"
              :amap-manager="amapManager">
              <el-amap-marker
                  v-if="marker.visible"
                  class="map-marker"
                  vid="component-marker"
                  :icon="marker.icon"
                  :position="marker.position">
              </el-amap-marker>
          </el-amap>
      </ion-content>
    </ion-content>
  </ion-page>
</template>
<script lang="ts">
import { AMapManager } from 'vue-amap';
import { Vue, Component, Prop } from "vue-property-decorator";

@Component({
    components: {
    },
})
export default class AppMobMapPage extends Vue {

    /**
     * 视图上下文参数
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    @Prop() context: any;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    @Prop() viewparams: any;

    /**
     * 关闭
     *
     * @type {*}
     * @memberof AppMobMapPage
     */      
    @Prop() close: any;

    /**
     * 地址
     *
     * @type {*}
     * @memberof AppMobMapPage
     */ 
    public address: string = '';

    /**
     * AMap SDK对象
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public amapManager: any = new AMapManager();

    /**
     * 地图标点信息
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public marker: any = {
      position: [0, 0],
      address: '',
      icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
      visible: false
    };

    /**
     * 事件集合
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public events: any = {};

    /**
     * 获取地址需求AMap插件对象
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public geocoder: any;

    /**
     * 当前 window
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public win: any;

    /**
     * 搜索服务
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public placeSearch: any;

    /**
     * 地图配置
     *
     * @type {*}
     * @memberof AppMobMapPage
     */
    public plugin = [{
        maximumAge: 0,           //定位结果缓存0毫秒，默认：0
        buttonPosition: 'RB',    //定位按钮停靠位置，默认：'LB'，左下角
        showButton: true,  //显示定位按钮，默认：true
        showMarker: true,  //定位成功后在定位到的位置显示点标记，默认：true
        showCircle: false,  //定位成功后用圆圈表示定位精度范围，默认：true
        panToLocation: true, //定位成功后将定位到的位置作为地图中心点，默认：true
        zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见
        enableHighAccuracy: true, // 是否使用高精度定位，默认为true
        extensions: 'all',
        pName: 'Geolocation',
        events: {
            init: (o: any) => {
              // o 是高德地图定位插件实例
              this.initCurAddress(o);
            }
        }
    }]

    /**
     * 初始化当前位置
     *
     * @type {*}
     * @memberof AppMobMapPage
     */ 
    initCurAddress(o: any) {
      o.getCurrentPosition((status: any, result: any) => {
          if (result && result.status != 0) {
            if (!this.marker.visible) {
              if (this.address) {
                this.handleSearch();
              } else {
                const position = [result.position.lng, result.position.lat];
                this.address = result.formattedAddress;
                Object.assign(this.marker, { position: position, address: this.address, visible: true });
              }
            }
          }
      });
    }

    /**
     * 生命周期
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    public created() {
      this.win = window as any;
      let amap: any = this.win.AMap;
      amap.plugin(["AMap.Geocoder"], () => {
          this.geocoder = new amap.Geocoder({
              extensions: "all",
          })
      });
      // 注册地图搜索服务
      amap.service(["AMap.PlaceSearch"], () => {
          this.placeSearch = new this.win.AMap.PlaceSearch({
              pageSize: 5, // 单页显示结果条数
              citylimit: false, // 是否强制限制在设置的城市内搜索
              panel: 'map__result', // 搜索列表的HTML容器id或容器元素
          });
      })
      // 监听搜索列表点击
      amap.event.addListener(this.placeSearch,"listElementClick", (e: any) => {
            if(e.data.location) {
                this.handleMarker(e.data.location.R, e.data.location.Q, this, false);
            }
      });
      if(this.viewparams) {
          this.initAddress();
      }
      this.initMapEvents();
    }

    /**
     * 初始化地图事件
     *
     * @memberof AppMapPosition
     */
    public initMapEvents() {
      const that: any = this;
      that.events = {
        click($event: any) {
            that.mapClick($event);
        },
      };
    }

    /**
     * 初始化地址
     *
     * @memberof AppMapPosition
     */
    public async initAddress() {
        const viewparams = this.viewparams;
        this.address = viewparams.address;
        const longitude = viewparams.longitude;
        const latitude = viewparams.latitude;
        if(longitude && latitude) {
            const position = [Number(longitude), Number(latitude)];
            Object.assign(this.marker, {
                position: position,
                address: this.address,
                visible: true,
            });
            if (!this.address) {
              const address = await this.getAddress(longitude, latitude).catch((error) => {
                console.warn(error);
              });
              if(address) {
                this.address = address as string;
              }
            }
        }  
    }

    /**
     * 搜索
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    public search($event: any) {
      const searchValue = $event.detail?.value;
      if (!Object.is(searchValue, this.address)) {
        this.address = searchValue;
        this.handleSearch();
      }
    }

    /**
     * 清空搜索列表
     *
     * @type {*}
     * @memberof AppMobMapPage
     */ 
    public clearSearchList() {
      if (this.placeSearch) {
        this.placeSearch.clear();
      }
      this.address = "";
      Object.assign(this.marker, { position: [0, 0], address: this.address, visible: false });
    }

    /**
     * 搜索地址
     * 
     * @memberof AppMapPosition
     */
    public handleSearch() {
        //  调用服务搜索结果
        if (this.placeSearch) {
          this.placeSearch.search(this.address, (status: any, result: any) => {
            if (status == 'complete' && result.info == 'OK') {
              console.warn('搜索成功');
            } else {
              console.warn('搜索失败');
            }
          })
        }
    }


    /**
     * 地图点击事件
     * 
     * @memberof AppMapPosition
     */
    public mapClick($event: any) {
      if(!$event && !$event.lnglat) {
          return;
      }
      const that = this;
      that.handleMarker($event.lnglat.lng, $event.lnglat.lat, that, false);
    }

    /**
     * 处理地图标点
     * 
     * @param {*} lng 经度
     * @param {*} lat 纬度
     * @param {*} that this指针
     * @param {boolean} flag 是否更新结果集
     * @memberof AppMapPosition
     */
    public async handleMarker(lng: any, lat: any, that: any, flag: boolean = true) {
        if (!lng && !lat) {
          return
        }
        const address = await this.getAddress(lng, lat).catch((error) => {
            console.warn(error);
        });
        if(!address) {
            return;
        }
        Object.assign(that.marker, { position: [lng, lat], address: address, visible: true });
        that.address = address;
    }    

    /**
     * 调用服务，根据经纬度获取地址信息
     * 
     * @param {*} lng 经度
     * @param {*} lat 纬度
     * @memberof AppMapPosition
     */
    public getAddress(lng: any, lat: any) {
        return new Promise((resolve, reject) => {
            this.geocoder.getAddress([lng,lat],(status: any, result: any) => {
                let address = null;
                if (status === 'complete' && result.info === 'OK') {
                    if (result && result.regeocode) {
                      address = result.regeocode.formattedAddress;
                    }
                }
                resolve(address);
            })
        })
    }

    /**
     * 确认
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    public onOK() {
        const data ={
          address: this.marker.address,
          longitude: this.marker.position[0] ? this.marker.position[0].toFixed(6) : null,
          latitude: this.marker.position[1] ? this.marker.position[1].toFixed(6) : null,
        }
        if (this.close && this.close instanceof Function) {
          this.close(data);
        }
    }
    
    /**
     * 取消
     *
     * @type {*}
     * @memberof AppMobMapPage
     */  
    public onCancel() {
        if (this.close && this.close instanceof Function) {
          this.close();
        }
    }
}
</script>
<style lang="less">
@import "./app-mob-map-page.less";
</style>